package com.components.update.util

import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.util.concurrent.TimeUnit
import kotlin.jvm.Throws

class HttpUtil {
    private val mOkHttpClient: OkHttpClient

    /**
     * 构造方法,配置OkHttpClient
     */
    init {
        //创建okHttpClient对象
        val builder = OkHttpClient.Builder()
            .retryOnConnectionFailure(true)
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
        mOkHttpClient = builder.build()
    }

    /**
     * @param url        下载链接
     * @param startIndex 下载起始位置
     * @param endIndex   结束为止
     * @param callback   回调
     * @throws IOException
     */
    @Throws(IOException::class)
    fun downloadFileByRange(url: String, startIndex: Long, endIndex: Long, callback: Callback) {
        // 创建一个Request
        // 设置分段下载的头信息。 Range:做分段数据请求,断点续传指示下载的区间。格式: Range bytes=0-1024或者bytes:0-1024
        val request = Request.Builder().header("RANGE", "bytes=$startIndex-")
            .url(url)
            .build()
        doAsync(request, callback)
    }

    @Throws(IOException::class)
    fun getContentLength(url: String, callback: Callback) {
        // 创建一个Request
        val request = Request.Builder()
            .addHeader("Connection", "close")
            .url(url)
            .build()
        doAsync(request, callback)
    }

    /**
     * 异步请求
     */
    @Throws(IOException::class)
    private fun doAsync(request: Request, callback: Callback) {
        //创建请求会话
        val call = mOkHttpClient.newCall(request)
        //同步执行会话请求
        call.enqueue(callback)
    }

    /**
     * 同步请求
     */
    @Throws(IOException::class)
    private fun doSync(request: Request): Response {

        //创建请求会话
        val call = mOkHttpClient.newCall(request)
        //同步执行会话请求
        return call.execute()
    }

    companion object {
        private const val CONNECT_TIMEOUT: Long = 30 //超时时间，秒
        private const val READ_TIMEOUT: Long = 30 //读取时间，秒
        private const val WRITE_TIMEOUT: Long = 30 //写入时间，秒

        /**
         * @return HttpUtil实例对象
         */
        var instance: HttpUtil? = null
            get() {
                if (field == null) {
                    synchronized(HttpUtil::class.java) {
                        if (field == null) {
                            field = HttpUtil()
                        }
                    }
                }
                return field
            }
    }

}
